#ifndef WEBRTC_PUB_HPP
#define WEBRTC_PUB_HPP

#include "rtc/rtc.hpp"
#include <nlohmann/json.hpp>
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>
#include <iomanip>
#include <sstream>
#include <memory>
#include <future>
#include <vector>
#include <functional>

#ifdef HAS_DRACO
#include "draco/compression/encode.h"
#include "draco/point_cloud/point_cloud_builder.h"
#include "draco/compression/decode.h"
#include "draco/io/point_cloud_io.h"
#endif

using std::shared_ptr;
using nlohmann::json;

class WebRTCClient {
public:
    // 构造函数和析构函数
    WebRTCClient(const std::string& robot_id = "ROBOT_001");
    ~WebRTCClient();

    // 初始化和连接
    bool initialize();
    std::string get_room_id();
    bool connect_to_room(const std::string& room_id);
    void disconnect();

    // 数据传输接口
    bool send_binary_data(const std::vector<uint8_t>& data);
    bool send_point_cloud_data(const std::vector<float>& points);
    bool send_point_cloud_json(const json& point_cloud_json);
    
    // Draco点云压缩功能
    bool send_compressed_point_cloud(const std::vector<float>& points);
    std::vector<uint8_t> compress_point_cloud_draco(const std::vector<float>& points);
    bool is_draco_available() const;
    
    // 状态查询
    bool is_connected() const;
    bool is_data_channel_ready() const;
    bool is_room_joined() const;
    size_t get_buffer_size() const;

    // 回调函数设置
    void set_connection_callback(std::function<void(bool)> callback);
    void set_data_received_callback(std::function<void(const std::vector<uint8_t>&)> callback);

private:
    // WebRTC核心组件
    shared_ptr<rtc::PeerConnection> peer_connection_;
    shared_ptr<rtc::WebSocket> websocket_;
    shared_ptr<rtc::DataChannel> data_channel_;
    
    // 配置参数
    std::string robot_id_;
    std::string current_room_id_;
    
    // 压缩配置
    bool enable_compression_;
    int draco_compression_level_;  // 0-10, 10为最高压缩比
    
    // 连接状态
    std::atomic<bool> is_initialized_;
    std::atomic<bool> is_connected_;
    std::atomic<bool> data_channel_ready_;
    std::atomic<bool> room_joined_;
    
    // 心跳相关
    std::atomic<bool> heartbeat_running_;
    std::thread heartbeat_thread_;
    
    // ICE candidates 收集
    std::vector<std::string> local_ice_candidates_;
    std::mutex ice_candidates_mutex_;
    std::atomic<bool> ice_gathering_complete_;
    
    // 数据传输配置
    static const size_t MAX_DATA_CHANNEL_SIZE = 64 * 1024;  // 64KB
    static const size_t RTC_BUFFER_THRESHOLD = 16 * 1024 * 1024; // 10MB
    
    // 回调函数
    std::function<void(bool)> connection_callback_;
    std::function<void(const std::vector<uint8_t>&)> data_received_callback_;
    
    // 内部方法
    void init_webrtc();
    void create_webrtc_offer();
    void setup_data_channel();
    void handle_websocket_message(const std::string& message);
    void handle_answer(const json& answer_data);
    void handle_ice_candidate(const json& candidate_data);
    
    // 心跳相关
    void start_heartbeat();
    void stop_heartbeat();
    void heartbeat_loop();
    
    // 消息创建和发送
    void send_room_action(const std::string& action_type);
    void send_ice_candidate_batch();
    json create_send_info_message(const std::string& room_id, const json& data);
    json create_offer_data(const std::string& offer_sdp);
    json create_ice_candidate_batch_data(const std::vector<std::string>& ice_candidates);
    
    // 数据包处理
    std::vector<uint8_t> create_data_packet(uint32_t message_id, uint32_t index, 
                                           uint32_t total, uint32_t data_type, 
                                           const std::vector<uint8_t>& data);
    std::vector<std::vector<uint8_t>> slice_binary_data(const std::vector<uint8_t>& data, 
                                                       size_t max_chunk_size = 64 * 1024);
    void wait_for_buffer_available();
    
    // JSON点云数据处理
    std::vector<uint8_t> json_to_binary(const json& point_cloud_json);
    
    // Draco压缩相关方法
#ifdef HAS_DRACO
    std::unique_ptr<draco::PointCloud> create_draco_point_cloud(const std::vector<float>& points);
    std::vector<uint8_t> encode_draco_point_cloud(const draco::PointCloud& point_cloud);
#endif
    
    // 工具函数
    std::string generate_message_id();
    std::string get_iso8601_timestamp();
    static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp);
};

#endif // WEBRTC_CLIENT_HPP